package org.esky.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.esky.reflect.entity.User;

/**
 * @author Jack.Xu
 * @ClassName: MyMethodRef
 * @Description: TODO
 * @author: Jack.Xu
 * @date: 2013年10月18日 下午1:54:22
 */
public class MyMethodRef {
	public static Object copy(Object object) throws Exception {
		// 获得对象的类型
		Class<?> classType = object.getClass();
		System.out.println("Class:" + classType.getName());
		// 通过默认构造方法创建一个新的对象
		Object objectCopy = classType.getConstructor(new Class[] {}).newInstance(new Object[] {});
		// 获得对象的所有属性
		Field fields[] = classType.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			String fieldName = field.getName();
			// serial自动生成需跳过
			if ("serialVersionUID".equals(fieldName)) {
				continue;
			}
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			// 获得和属性对应的getXXX()方法的名字
			String getMethodName = "get" + firstLetter + fieldName.substring(1);
			// 获得和属性对应的setXXX()方法的名字
			String setMethodName = "set" + firstLetter + fieldName.substring(1);
			// 获得和属性对应的getXXX()方法
			Method getMethod = classType.getMethod(getMethodName, new Class[] {});
			// 获得和属性对应的setXXX()方法
			Method setMethod = classType.getMethod(setMethodName, new Class[] { field.getType() });
			// 调用原对象的getXXX()方法
			Object value = getMethod.invoke(object, new Object[] {});
			System.out.println(fieldName + ":" + value);
			// 调用拷贝对象的setXXX()方法
			setMethod.invoke(objectCopy, new Object[] { value });
		}
		return objectCopy;
	}
	
	public static void sayHello() throws Exception {
		// 通过类装载器获取User类对象  
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		Class<?> clazz = loader.loadClass("org.esky.entity.User");
		Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, Integer.class);
		User user = (User) constructor.newInstance("joy", 13);
		// 取消Java语言访问检查以访问protected方法
		Method sayHello = clazz.getDeclaredMethod("sayHello", (Class[]) null);
		sayHello.setAccessible(true);
		sayHello.invoke(user, (Object[])null);
	}
}
